﻿using SD.Common;
using SD.Infrastructure.DTOBase;
using SD.Infrastructure.WPF.Caliburn.Aspects;
using SD.Infrastructure.WPF.Caliburn.Base;
using SD.Infrastructure.WPF.Extensions;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel.Extensions;
using System.Threading.Tasks;
using System.Windows;
using SlamDunk.MES.IAppService.DTOs.Outputs.PlanContext;
using SlamDunk.MES.IAppService.DTOs.Outputs.StockContext;
using SlamDunk.MES.IAppService.Interfaces;
using SlamDunk.ValueObjects.Enums;

namespace SlamDunk.MES.Client.ViewModels.StockOutOrder
{
    /// <summary>
    /// 出库单据查看ViewModel
    /// </summary>
    public class LookViewModel : ScreenBase
    {
        #region # 字段及构造器

        /// <summary>
        /// 库存单据服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IStockOrderContract> _iStockOrderContract;

        /// <summary>
        /// 资源定义服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IPlanContract> _iPlanContract;

        /// <summary>
        /// 依赖注入构造器
        /// </summary>
        public LookViewModel(ServiceProxy<IStockOrderContract> iStockOrderContract, ServiceProxy<IPlanContract> iPlanContract)
        {
            this._iStockOrderContract = iStockOrderContract;
            this._iPlanContract = iPlanContract;
        }

        #endregion

        #region 属性
        #region 单据编号
        /// <summary>
        /// 单据编号
        /// </summary>
        [DependencyProperty]
        public string Number { get; set; }
        #endregion

        #region 源单据类型
        /// <summary>
        /// 源单据类型
        /// </summary>
        [DependencyProperty]
        public string SourceOrderType { get; set; }
        #endregion

        #region 源储存类型
        /// <summary>
        /// 源储存类型
        /// </summary>
        [DependencyProperty]
        public string SourceStorageLocationType { get; set; }
        #endregion

        #region 源储存位置
        /// <summary>
        /// 源储存位置
        /// </summary>
        [DependencyProperty]
        public string SourceStorageLocation { get; set; }
        #endregion

        #region 单据类型
        /// <summary>
        /// 单据类型
        /// </summary>
        [DependencyProperty]
        public string StockOrderClass { get; set; }
        #endregion

        #region 源单据信息
        /// <summary>
        /// 源单据信息
        /// </summary>
        [DependencyProperty]
        public string SourceOrder { get; set; }
        #endregion

        #region 目标库类型
        /// <summary>
        /// 目标库类型
        /// </summary>
        [DependencyProperty]
        public string TargetStorageLocationType { get; set; }
        #endregion

        #region 目标库位置
        /// <summary>
        /// 目标库位置
        /// </summary>
        [DependencyProperty]
        public string TargetStorageLocation { get; set; }
        #endregion

        #region 描述
        /// <summary>
        /// 描述
        /// </summary>
        [DependencyProperty]
        public string Description { get; set; }
        #endregion

        #region 出库单据明细列表
        /// <summary>
        /// 出库单据明细集合
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<StockOrderDetailInfo> DetailParams { get; set; }
        #endregion

        #region 物料需求列表
        /// <summary>
        /// 物料需求列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<ExecutionMaterialAskInfo> ExecutionMaterialAsks { get; set; }
        #endregion

        #region 工厂模型
        /// <summary>
        /// 工厂模型
        /// </summary>
        [DependencyProperty]
        public string FacilityName { get; set; }
        #endregion
        #endregion

        #region 方法
        #region 加载 —— async Task Load(StockOutOrderInfo stockOutOrderInfo)
        /// <summary>
        /// 加载
        /// </summary>
        public async Task Load(StockOutOrderInfo stockOutOrderInfo)
        {
            this.Number = stockOutOrderInfo.Number;
            this.SourceOrderType = stockOutOrderInfo.SourceOrderType == null ? null : EnumExtension.GetEnumMember(stockOutOrderInfo.SourceOrderType);
            this.SourceStorageLocationType = EnumExtension.GetEnumMember(stockOutOrderInfo.SourceStorageLocationType);
            this.SourceStorageLocation = stockOutOrderInfo.SourceStorageLocationName;
            this.FacilityName = stockOutOrderInfo.FacilityInfo?.Name;
            PageModel<StockOrderClassInfo> StockOrderClassInfos = await Task.Run(() => this._iStockOrderContract.Channel.GetStockOrderClassesByPage(null, StockDirectionType.Output, null, null, 1, int.MaxValue));
            this.StockOrderClass = StockOrderClassInfos.Datas.Where(x => x.Id == stockOutOrderInfo.StockOrderClassId).FirstOrDefault()?.Name;
            this.SourceOrder = stockOutOrderInfo.SourceOrderName;
            this.TargetStorageLocationType = EnumExtension.GetEnumMember(stockOutOrderInfo.TargetStorageLocationType);
            this.TargetStorageLocation = stockOutOrderInfo.TargetStorageLocationName;
            this.Description = stockOutOrderInfo.Description;
            IEnumerable<StockOrderDetailInfo> StockInOrderInfos = await Task.Run(() => this._iStockOrderContract.Channel.GetStockOrderDetails(stockOutOrderInfo.Id));
            DetailParams = new ObservableCollection<StockOrderDetailInfo>(StockInOrderInfos);

            if (stockOutOrderInfo.SourceOrderType == ValueObjects.Enums.SourceOrderType.ExecutionPlan)
            {
                this.ExecutionMaterialAsks = new ObservableCollection<ExecutionMaterialAskInfo>(await Task.Run(() => this._iPlanContract.Channel.GetExecutionMaterialAsks(Guid.Parse(stockOutOrderInfo.SourceOrderId))));
            }
            if (stockOutOrderInfo.SourceOrderType == ValueObjects.Enums.SourceOrderType.ProductionPlan)
            {
                IEnumerable<ProductionMaterialAskInfo> productionMaterialAskInfos = await Task.Run(() => this._iPlanContract.Channel.GetProductionMaterialAsks(Guid.Parse(stockOutOrderInfo.SourceOrderId)));
                IList<ExecutionMaterialAskInfo> materialAsks = new List<ExecutionMaterialAskInfo>();
                foreach (ProductionMaterialAskInfo productionMaterialAskInfo in productionMaterialAskInfos)
                {
                    ExecutionMaterialAskInfo materialAsk = new ExecutionMaterialAskInfo
                    {
                        Id = productionMaterialAskInfo.Id,
                        Number = productionMaterialAskInfo.Number,
                        Name = productionMaterialAskInfo.Number,
                        AddedTime = productionMaterialAskInfo.AddedTime,
                        MaterialId = productionMaterialAskInfo.MaterialId,
                        MaterialLotId = productionMaterialAskInfo.MaterialLotId,
                        Quantity = productionMaterialAskInfo.Quantity,
                        Sort = productionMaterialAskInfo.Sort,
                        Description = productionMaterialAskInfo.Description,
                        MaterialInfo = productionMaterialAskInfo.MaterialInfo,
                        MaterialLotInfo = productionMaterialAskInfo.MaterialLotInfo
                    };
                    materialAsks.Add(materialAsk);
                }
                this.ExecutionMaterialAsks = new ObservableCollection<ExecutionMaterialAskInfo>(materialAsks);
            }
        }
        #endregion
        #endregion
    }
}
